"""
Lovingly based on the demo file provided by the Albow library.
"""

screen_size = (800, 600)
flags = 0
frame_time = 50 # ms

import os, sys
from os.path import dirname as d
sys.path.insert(1, d(d(os.path.abspath(sys.argv[0]))))
from functools import partial

import pygame
pygame.mixer.pre_init(44100, -16, 2, 1024 * 3)
pygame.init()
from pygame.color import Color
from pygame.locals import *

import data
from albow.resource import get_image, get_font
from fix import fix_resource
fix_resource()
import constants as c
import sounds

from albow.controls import Button, Image, ImageButton, Label
from albow.shell import Shell
from albow.layout import Column
from albow.screen import Screen
from albow.text_screen import TextScreen
from albow.dialogs import alert
from albow.table_view import TableView, TableColumn
from albow import theme

from game import play_game
from popup import popup, game_complete

#--------------------------------------------------------------------------------
#
#    Buttons
#
#--------------------------------------------------------------------------------

class MenuScreen(Screen):

    def __init__(self, shell):
        Screen.__init__(self, shell)
        self.shell = shell
        title = Image("title.png")
        self.bg_image = get_image("background.png")

        def screen_button(imagename, screenname):
            def update_then_show():
                shell.make_hiscores()
                screen = getattr(shell, screenname)
                return shell.show_screen(screen)
            return ImageButton(image=imagename, action=update_then_show)

        menu = Column([
            ImageButton("play.png", action=self.run_game),
            screen_button("hiscores.png", 'text_screen'),
            ImageButton("quit.png", action=shell.quit),
        ], align = 'l')
        contents = Column([
            title,
            menu,
        ], align = 'c', spacing = 20)
        self.add(contents)

    def show_finish_screen(self):
        self.shell.show_screen(self.text_screen)

    def run_game(self):
        class G: pass
        G.name = "James Wobble"
        G.timelimit = 15
        popup(self.shell.surface, G)
        scores = self.shell.play_game(self.shell.surface, background())
        game_complete(self.shell.surface, scores)

    def quit(self):
        sys.exit(0)

#--------------------------------------------------------------------------------

class HiScoresScreen(Screen):

   def __init__(self, shell, scores):
      Screen.__init__(self, shell)

      image = Image(get_image("hiscores_text.png"))
      table = HiScoresTable(scores)
      back = Button("Menu", action = shell.show_menu)
      back.fg_color = c.GREY
      contents = Column([image, table, back], spacing = 30)
      self.add_centered(contents)

#--------------------------------------------------------------------------------

selected_table_row = 0

class HiScoresTable(TableView):

    def __init__(self, scores):
        TableView.__init__(self)
        self._scores = scores
    columns = [
        TableColumn("rank", 50),
        TableColumn("name", 70),
        TableColumn("saved perls", 100, 'r', "%s"),
        TableColumn("perls fired", 100, 'r', "%s"),
        TableColumn("frugality", 100, 'r', "%0.1f"),
    ]

    def num_rows(self):
        return len(self._scores)

    def row_data(self, i):
        return self._scores[i]

    def row_is_selected(self, i):
        return selected_table_row == i

    def click_row(self, i, e):
        global selected_table_row
        selected_table_row = i

#--------------------------------------------------------------------------------

def wrap_scores(scores):
    for rank, (name, saved, total) in enumerate(scores):
        try:
            yield rank + 1, name, saved, total, float(saved) / float(total) * 100
        except (ValueError, ZeroDivisionError):
            yield rank + 1, name, saved, total, -1

class GameShell(Shell):

    def __init__(self, display, game):
        Shell.__init__(self, display)
        self.make_hiscores()
        self.play_game = game
        self.menu_screen = MenuScreen(self) # Do this last
        self.set_timer(frame_time)
        self.show_menu()

    def make_hiscores(self):
        high_scores = list(wrap_scores(data.highscores()))

        self.text_screen = HiScoresScreen(self, high_scores)
        self.text_screen.bg_image = get_image("background.png")

    def show_menu(self):
        self.show_screen(self.menu_screen)

def background():
    return get_image("game-bg.png")

def make_theme(root):
    root.fg_color = c.GREY
    root.Button.fg_color = c.GREY
    root.Button.highlight_color = c.WHITE

def main():
    display = pygame.display.set_mode(screen_size, flags)
    sounds.play_bgmusic("impbgm1.ogg")
    pygame.display.set_caption("James Wobble | Professional Perl Collector")
    theme.root.fg_color = (46, 52, 54)
    shell = GameShell(display, play_game)
    shell.run()
